package org.example.mppg.domain.entity;

import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.annotation.*;
import com.github.javafaker.Faker;
import lombok.Data;
import org.example.mppg.handler.PointTypeHandler;
import org.example.mppg.util.DateUtil;
import org.example.mppg.util.GeoJSONUtils;
import org.locationtech.jts.geom.Geometry;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 学生信息表
 * </p>
 *
 * @author bo
 * @since 2024-10-14
 */
@TableName("student")
@Data
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 自增主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 姓名
     */
    @TableField("stu_name")
    private String stuName;

    /**
     * 年级编号
     */
    @TableField("grade_no")
    private Integer gradeNo;

    /**
     * 班级编号
     */
    @TableField("class_no")
    private Integer classNo;

    /**
     * 额外信息
     */
    @TableField("info")
    private JSONObject info;

    /**
     * 创建时间，默认为当前时间
     */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 更新时间，默认为当前时间
     */
    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    /**
     * 是否删除标志，默认为0（未删除）
     */
    @TableField("is_deleted")
    @TableLogic
    private Integer isDeleted;

    @TableField(value = "address_geo",typeHandler = PointTypeHandler.class)
    private Geometry addressGeo;

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", stuName=" + stuName +
                ", gradeNo=" + gradeNo +
                ", classNo=" + classNo +
                ", info=" + info +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                ", isDeleted=" + isDeleted +
                "}";
    }

    public static List<Student> GenerateStudents(int num) {
        return IntStream.range(0, num)
                .mapToObj(i -> Student.generate())
                .collect(Collectors.toList());
    }


    public static Student generate() {
        Student student = new Student();
        Faker faker = new Faker(new Locale("zh-CN"));
        Random random = new Random();

        String wktString = "POINT (116.3840961495821 40.10829581003965)";
        Geometry geometry = GeoJSONUtils.wkt2Geometry(wktString);
        student.setAddressGeo(geometry);
        student.setStuName(faker.name().fullName());
        student.setGradeNo(random.nextInt(12) + 1);
        student.setClassNo(random.nextInt(10) + 1);
        student.setInfo(generateInfo(faker));
        student.setCreateTime(DateUtil.randomLocalDateTime("2010-10-11", "2024-10-11"));
        student.setUpdateTime(DateUtil.randomLocalDateTime("2010-10-11", "2024-10-11"));
        return student;
    }

    private static JSONObject generateInfo(Faker faker) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        boolean includeAddress = random.nextBoolean();
        boolean includeFatherName = random.nextBoolean();
        boolean includeMotherName = random.nextBoolean();
        boolean includeAge = random.nextBoolean();

        JSONObject jsonObject = new JSONObject();

        if (includeAddress) {
            jsonObject.put("address", faker.address().fullAddress());
        }
        if (includeFatherName) {
            jsonObject.put("father_name", faker.name().fullName());
        }
        if (includeMotherName) {
            jsonObject.put("mother_name", faker.name().fullName());
        }
        if (includeAge) {
            jsonObject.put("age", faker.number().numberBetween(6, 18));
        }

        return jsonObject;
    }
}
